package com.hd123.rumba.qt.result;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import net.sf.hibernate.Hibernate;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.type.Type;

import com.hd123.rumba.exception.BusinessException;
import com.hd123.rumba.qt.QTConstants;
import com.hd123.rumba.qt.QueryResultSession;
import com.hd123.rumba.qt.def.IQueryDef;
import com.hd123.rumba.runtime.Manager;
import com.hd123.rumba.sql.JdbcRow;
import com.hd123.rumba.user.IUser;
import com.hd123.rumba.util.StringUtil;

public class QueryResultMgr extends Manager implements IQueryResultMgr {

  public QueryResultDescription findQrdByQrd(QueryResultDescription qrd) throws HibernateException,
      BusinessException {
    QueryResultDescription result = null;
    List list = getSession().find(
        "from QueryResultDescription qrd where qrd.qdUuid=? and qrd.qdTime=? and qrd.userUuid=? "
            + "order by qrd.startTime desc", new Object[] {
            qrd.getQdUuid(), qrd.getQdTime(), qrd.getUserUuid() }, new Type[] {
            Hibernate.STRING, Hibernate.TIMESTAMP, Hibernate.STRING });
    for (int i = 0; i < list.size(); ++i) {
      QueryResultDescription t = (QueryResultDescription) list.get(i);
      if (qrd.getQueryCriteria() == null || qrd.getQueryCriteria().isSame(t.getQueryCriteria())) {
        result = t;
        break;
      }
    }
    return result;
  }

  public List creatQrdList(QueryResultDescription qrd) throws HibernateException, BusinessException {
    List list = getSession().find(
        "from QueryResultDescription qrd where qrd.qdName=? and qrd.qdTime=? and qrd.userUuid=? "
            + "order by qrd.startTime desc", new Object[] {
            qrd.getQdName(), qrd.getQdTime(), qrd.getUserUuid() }, new Type[] {
            Hibernate.STRING, Hibernate.TIMESTAMP, Hibernate.STRING });
    return list;
  }

  public QueryResultDescription findQrdByNameUser(String base, String name, Date time, IUser user)
      throws HibernateException, BusinessException {
    QueryResultDescription qrd = null;
    List list = getSession().find(
        "from QueryResultDescription qrd where qrd.qdName=? and qrd.qdTime=? and qrd.userUuid=? "
            + "order by qrd.startTime desc", new Object[] {
            name, time, user.getUuid() }, new Type[] {
            Hibernate.STRING, Hibernate.TIMESTAMP, Hibernate.STRING });
    if (list.size() > 0) {
      qrd = (QueryResultDescription) list.get(0);
    }
    return qrd;
  }

  public QueryResultDescription findQrd(IQueryDef queryDef, Date time, IUser user)
      throws BusinessException, HibernateException {
    QueryResultDescription qrd = null;
    List list = getSession().find(
        "from QueryResultDescription qrd where qrd.qdUuid = ? and qrd.qdTime = ? and qrd.userUuid = ?"
            + " order by qrd.startTime desc", new Object[] {
            queryDef.getUuid(), time, user.getUuid() }, new Type[] {
            Hibernate.STRING, Hibernate.TIMESTAMP, Hibernate.STRING });
    if (list.size() > 0) {
      qrd = (QueryResultDescription) list.get(0);
    }
    return qrd;
  }

  public List findExpiredResults() throws HibernateException {
    Date d = StringUtil.addDate(new Date(), Calendar.DATE, -QTConstants.QRLIFE);
    return getSession().find("from QueryResultDescription qrd where qrd.startTime < ?", d,
        Hibernate.TIMESTAMP);
  }

  public QueryResultDescription findQrdByUuid(String uuid) throws HibernateException {
    List list = getSession().find("from QueryResultDescription qrd where qrd.uuid=?", uuid,
        Hibernate.STRING);
    if (list != null && list.size() > 0)
      return (QueryResultDescription) list.get(0);
    else
      return null;
  }

  public void removeQrd(QueryResultDescription qrd) throws HibernateException {
    getSession().delete(qrd);
  }

  public void saveQrd(QueryResultDescription qrd) throws HibernateException {
    getSession().saveOrUpdate(qrd);
  }

  public List<QueryResultDescription> findFinishedQueries(IUser user, String query_uuid)
      throws Exception {
    return getSession().find(
        "from QueryResultDescription qrd "
            + "where qrd.userUuid=? and qrd.qdUuid=? and qrd.resultCount>=0 "
            + "order by qrd.startTime desc", new Object[] {
            user.getUuid(), query_uuid }, new Type[] {
            Hibernate.STRING, Hibernate.STRING });
  }

  public List<QueryResultDescription> findRunningQueries(IUser user, String query_uuid)
      throws BusinessException, HibernateException {
    return getSession().find(
        "from QueryResultDescription qrd "
            + "where qrd.userUuid=? and qrd.qdUuid=? and qrd.resultCount=? "
            + "order by qrd.startTime desc", new Object[] {
            user.getUuid(), query_uuid, QueryResultDescription.RESULTCOUNT_RUNNING }, new Type[] {
            Hibernate.STRING, Hibernate.STRING, Hibernate.INTEGER });
  }

  public List<QueryResultDescription> findAllResults(String query_uuid) throws BusinessException,
      HibernateException {
    return getSession().find(
        "from QueryResultDescription qrd where qrd.qdUuid=? " + "order by qrd.startTime desc",
        new Object[] {
          query_uuid }, new Type[] {
            Hibernate.STRING, Hibernate.STRING });
  }

  public List<QueryResultDescription> findAllResults(IUser user, String query_uuid)
      throws BusinessException, HibernateException {
    return getSession().find(
        "from QueryResultDescription qrd where qrd.userUuid=? and qrd.qdUuid=? "
            + "order by qrd.startTime desc", new Object[] {
            user.getUuid(), query_uuid }, new Type[] {
            Hibernate.STRING, Hibernate.STRING });
  }

  public JdbcRow findResultRow(QueryResultDescription qrd, String uuid) throws HibernateException,
      SQLException {
    JdbcRow row = null;
    PreparedStatement pstm = null;
    ResultSet rs = null;
    try {
      Connection conn = QueryResultSession.getSession().connection();
      pstm = conn.prepareStatement("select * from " + qrd.getTableName() + " where uuid = ?");
      pstm.setString(1, uuid);
      rs = pstm.executeQuery();
      ResultSetMetaData rsmd = rs.getMetaData();
      int i = rsmd.getColumnCount();
      if (rs.next()) {
        row = new JdbcRow();
        for (int k = 1; k <= i; k++) {
          String s = rsmd.getColumnName(k);
          Object obj = rs.getObject(k);
          row.put(s, obj);
        }
      }
    } finally {
      if (rs != null)
        rs.close();
      if (pstm != null)
        pstm.close();
      QueryResultSession.closeSession();
    }
    return row;
  }
}
